from app import db
from datetime import datetime, timedelta
import math
from sqlalchemy import func

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    points = db.Column(db.Integer, default=0)  # 总积分
    last_daily_points = db.Column(db.DateTime)  # 上次获得每日积分的时间
    consecutive_days = db.Column(db.Integer, default=0)  # 连续学习天数
    
    @staticmethod
    def get_or_create_default_user():
        """获取或创建默认用户"""
        user = User.query.first()
        if not user:
            user = User()
            db.session.add(user)
            db.session.commit()
        return user
    
    def add_points(self, points):
        """添加积分"""
        self.points += points
        db.session.commit()
    
    def check_daily_points(self):
        """检查并添加每日登录积分"""
        now = datetime.utcnow()
        if not self.last_daily_points:
            self.consecutive_days = 1
            self.last_daily_points = now
            self.add_points(10)  # 首次登录奖励
            return {'points': 10, 'message': '首次登录奖励: +10分'}
            
        # 检查是否是新的一天
        last_date = self.last_daily_points.date()
        today = now.date()
        
        if today > last_date:
            # 检查是否是连续的下一天
            if today == last_date + timedelta(days=1):
                self.consecutive_days += 1
                bonus = min(self.consecutive_days * 2, 20)  # 连续登录额外奖励，最高20分
            else:
                self.consecutive_days = 1
                bonus = 0
                
            base_points = 10  # 每日基础积分
            total_points = base_points + bonus
            
            self.last_daily_points = now
            self.add_points(total_points)
            
            message = f'每日登录: +{base_points}分'
            if bonus > 0:
                message += f'\n连续登录{self.consecutive_days}天: +{bonus}分'
            
            return {'points': total_points, 'message': message}
        
        return None

class PointsRecord(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    points = db.Column(db.Integer, nullable=False)
    reason = db.Column(db.String(200), nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)

class Word(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    word = db.Column(db.String(100), unique=True, nullable=False)
    pronunciation = db.Column(db.String(200))
    audio_url = db.Column(db.String(500))
    example = db.Column(db.Text)
    translation = db.Column(db.Text)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    last_review = db.Column(db.DateTime, default=datetime.utcnow)
    next_review_date = db.Column(db.DateTime, default=datetime.utcnow)
    review_count = db.Column(db.Integer, default=0)
    mastered = db.Column(db.Boolean, default=False)
    
    def get_next_review_interval(self):
        intervals = [
            1440,    # 1天
            2880,    # 2天
            4320,    # 3天
            7200,    # 5天
            10080,   # 7天
            20160,   # 14天
            40320    # 28天 - 最后一次复习
        ]
        if self.review_count >= len(intervals):
            return intervals[-1]
        return intervals[self.review_count]
    
    def update_review_status(self, mastered=False):
        self.review_count += 1
        self.last_review = datetime.utcnow()
        
        if self.review_count >= 7:
            self.mastered = mastered
            if not mastered:
                self.review_count = 0
        
        interval = self.get_next_review_interval()
        self.next_review_date = self.last_review + timedelta(minutes=interval)
        
        db.session.commit()
    
    @staticmethod
    def get_daily_words(limit=10):
        now = datetime.utcnow()
        return Word.query.filter(
            Word.next_review_date <= now,
            Word.mastered == False
        ).order_by(Word.next_review_date).limit(limit).all()
    
    def __repr__(self):
        return f'<Word {self.word}>' 
    
    @staticmethod
    def get_statistics():
        """获取学习统计数据"""
        total_words = Word.query.count()
        mastered_words = Word.query.filter_by(mastered=True).count()
        in_progress = Word.query.filter_by(mastered=False).count()
        
        # 获取最近7天每天的新增单词数
        seven_days_ago = datetime.utcnow() - timedelta(days=7)
        daily_new_words = db.session.query(
            func.date(Word.created_at).label('date'),
            func.count(Word.id).label('count')
        ).filter(
            Word.created_at >= seven_days_ago
        ).group_by(
            func.date(Word.created_at)
        ).all()
        
        # 获��复习次数分布
        review_distribution = db.session.query(
            Word.review_count,
            func.count(Word.id).label('count')
        ).group_by(Word.review_count).all()
        
        return {
            'total_words': total_words,
            'mastered_words': mastered_words,
            'in_progress': in_progress,
            'daily_new_words': daily_new_words,
            'review_distribution': review_distribution
        }
    
    def award_points_for_review(self):
        """完成单词复习时奖励积分"""
        user = User.get_or_create_default_user()
        points = 0
        message = []
        
        # 基础复习积分
        base_points = 2
        points += base_points
        message.append(f'完成复习: +{base_points}分')
        
        # 如果是最后一次复习且标记为已掌握
        if self.review_count >= 7 and self.mastered:
            mastery_bonus = 10
            points += mastery_bonus
            message.append(f'完全掌握: +{mastery_bonus}分')
        
        user.add_points(points)
        
        # 记录积分历史
        record = PointsRecord(
            user_id=user.id,
            points=points,
            reason='\n'.join(message)
        )
        db.session.add(record)
        db.session.commit()
        
        return {'points': points, 'message': '\n'.join(message)}

class Homework(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    subject = db.Column(db.String(20), nullable=False)
    content = db.Column(db.Text, nullable=False)
    hours = db.Column(db.Integer, default=0)
    minutes = db.Column(db.Integer, default=0)
    total_minutes = db.Column(db.Integer, nullable=False)
    created_at = db.Column(db.DateTime, default=datetime.utcnow)
    
    @classmethod
    def get_recent_homework(cls):
        """获取最近三天的作业记录"""
        three_days_ago = datetime.utcnow() - timedelta(days=3)
        return cls.query.filter(
            cls.created_at >= three_days_ago
        ).order_by(
            cls.created_at.desc()
        ).all()
    
    @classmethod
    def get_total_study_time(cls):
        """获取最近三天的总学习时间"""
        three_days_ago = datetime.utcnow() - timedelta(days=3)
        recent_homework = cls.query.filter(
            cls.created_at >= three_days_ago
        ).all()
        
        # 按科目统计学习时间
        subject_times = {}
        for hw in recent_homework:
            if hw.subject not in subject_times:
                subject_times[hw.subject] = 0
            subject_times[hw.subject] += hw.total_minutes
        
        return subject_times